package com.guinea.web.controller.uploadify;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.guinea.cache.SysCache;
import com.guinea.datadb.mongo.FileOperatorRecord;
import com.guinea.datadb.mongo.UploadConfig;
import com.guinea.dic.BooleanEnum;
import com.guinea.dic.FilefunctionType;
import com.guinea.profession.dao.mongo.FileOperatorRecordRepository;
import com.guinea.profession.dao.mongo.UploadConfigRepository;
import com.guinea.util.CommonToolsUtil;
import com.guinea.util.date.JodatimeUtil;
import com.guinea.util.file.FileContents;
import com.guinea.web.BaseFormController;
import com.guinea.web.model.Mime_types;
import com.guinea.web.model.User;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * @author: shiky
 * @describle:文件上传
 * @dateTime: 2016/2/18
 */
//@Controller
public class FileUploadifyController extends BaseFormController {

    private static Logger logger = LoggerFactory.getLogger(FileUploadifyController.class);

//    @Autowired
//    private UploadConfigRepository uploadConfigRepository;
//
//    @Autowired
//    private FileOperatorRecordRepository fileOperatorRecordRepository;

//    @Autowired
//    private MongoTemplate mongoTemplate;

    @RequestMapping(value = "/uploadify/uploadify", method = RequestMethod.GET)
    public String file_uploadify(HttpServletRequest request, HttpServletResponse response) {
        UploadConfig uploadConfig = SysCache.uploadConfigCache.get(0);
        List<Mime_types> mime_types = uploadConfig.getMime_types();
        String mime_type_str = null;
        try {
            mime_type_str = "mime_types:" + new ObjectMapper()
                    .writeValueAsString(mime_types);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        request.setAttribute("mime_type_str", mime_type_str);
        request.setAttribute("chunk_size", uploadConfig.getAllMaxSize() + "mb");
        request.setAttribute("max_file_size", uploadConfig.getFileMaxSize() + "mb");

		/*UploadConfig uploadConfig = new UploadConfig();
        uploadConfig.setAllMaxSize(600);
        uploadConfig.setFileMaxSize(600);
        uploadConfig.setIsReName(Short.valueOf("1"));
        uploadConfig.setIsDragdrop(Short.valueOf("1"));
        uploadConfig.setCacheSize(6);
        uploadConfig.setSavePath("D:\\tessdata\\mefiles");
        List<Mime_types> fileExts = Lists.newArrayList();
        Mime_types fileExtDocument = new Mime_types("documentExt","doc,docx,xls,xlsx,txt");
        Mime_types fileExtFile = new Mime_types("fileExt","zip,rar,7z,rar,log");
        Mime_types fileExtImage = new Mime_types("imageExt","jpg,png,jpeg,gif,ico,bmp");
        fileExts.add(fileExtDocument);
        fileExts.add(fileExtFile);
        fileExts.add(fileExtImage);
        uploadConfig.setMime_types(fileExts);
        uploadConfigRepository.save(uploadConfig);*/

//        mongoTemplate.insert(uploadConfig);
//        List<UploadConfig> uploadConfigs= uploadConfigRepository.findAll();
//        String str =JSON.toJSONString(uploadConfigs);
//        logger.debug("======"+str);
        return "uploadify/uploadify";
    }

    @RequestMapping(value = "/uploadify/upload", method = RequestMethod.POST)
    public void file_upload(HttpServletRequest request, HttpServletResponse response) {
        UploadConfig uploadConfig = SysCache.uploadConfigCache.get(0);
        if (null != uploadConfig) {
            //真实目录名
            String filePath = uploadConfig.getSavePath();
            //缓存目录
            CommonToolsUtil.ncheckFDir(FileContents.CATCHPATH);
            CommonToolsUtil.ncheckFDir(filePath);
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);
            if (isMultipart) {
                List<FileItem> items = null;
                // 设置最大文件尺寸
                long sizeMax = uploadConfig.getAllMaxSize() * 1024 * 1024;
                DateTime dateTime = new DateTime();
                try {
                    items = initConfig(sizeMax, uploadConfig, request, response).parseRequest(request);
                    if (null != items && items.size() > 0) {
                        for (FileItem item : items) {
                            //如果fileitem中封装的是上传文件
                            if (!item.isFormField()) {
                                processFileUpload(item, sizeMax, dateTime, filePath);
                            }
                        }
                        succMesg(request, response, "上传成功");
                    } else {
                        errorMsg(request, response);
                    }
                } catch (FileUploadException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /***
     * 上传业务处理
     *
     * @param item
     * @param sizeMax
     * @param dateTime
     * @param filePath
     * @throws Exception
     */
    private void processFileUpload(FileItem item, long sizeMax, DateTime dateTime, String filePath) throws Exception {
        item.getString("UTF-8");
        String fileName = StringUtils.trim(item.getName());
        long fileSize = item.getSize();
        if (StringUtils.isNotBlank(fileName) && fileSize > 0) {
            //检查文件大小
            if (fileSize > sizeMax) {
                logger.warn("文件大小超过限制!!!");
                return;
            }
            //检查扩展名
            String fileExt = StringUtils.trim(fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase());
            String newFileName = dateTime.toString("yyyyMMddHHmmss") + "_" + new Random().nextInt(1000) + "." + fileExt;
            //获取item中的上传文件的输入流
            InputStream in = item.getInputStream();
            //创建一个文件输出流
            FileOutputStream out = new FileOutputStream(filePath + FileContents.SEP + newFileName);
            //创建一个缓冲区
            byte buffer[] = new byte[3624];
            //判断输入流中的数据是否已经读完的标识
            int len = 0;
            //循环将输入流读入到缓冲区当中，(len=in.read(buffer))>0就表示in里面还有数据
            while ((len = in.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
            //关闭输入流
            in.close();
            //关闭输出流
            out.close();
            //写入数据库
            FileOperatorRecord fileOperatorRecord = new FileOperatorRecord();
            Subject subject = SecurityUtils.getSubject();
            User user = (User) subject.getPrincipal();
            fileOperatorRecord.setSavePath(filePath);
            fileOperatorRecord.setLoginName(user.getLoginname());
            String timeStr = JodatimeUtil.getDateTimeToStr(dateTime, JodatimeUtil.fmtSSS);
            fileOperatorRecord.setOperatorTime(timeStr);
            fileOperatorRecord.setSaveTime(timeStr);
            fileOperatorRecord.setSaveName(newFileName);
            fileOperatorRecord.setOrgName(fileName);
            fileOperatorRecord.setFunctionType(FilefunctionType.SYS.getCode());
//            fileOperatorRecordRepository.save(fileOperatorRecord);
        }
    }

    @RequestMapping(value = "/uploadify/uploadConfig", method = RequestMethod.GET)
    public String uploadify_config(ModelMap model) {
        UploadConfig uploadConfig = null;
//        List<UploadConfig> uploadConfigs = uploadConfigRepository.findAll();
        List<UploadConfig> uploadConfigs = Lists.newArrayList();
        if (null != uploadConfigs && uploadConfigs.size() > 0) {
            uploadConfig = uploadConfigs.get(0);
        } else {
            uploadConfig = new UploadConfig();
        }
        String documentExt = "", fileExt = "", imageExt = "";
        List<Mime_types> mime_types = uploadConfig.getMime_types();
        if (null != mime_types && mime_types.size() > 0) {
            for (Mime_types temp : mime_types) {
                if (null != temp) {
                    switch (temp.getTitle()) {
                        case "documentExt":
                            documentExt = temp.getExtensions();
                            break;
                        case "fileExt":
                            fileExt = temp.getExtensions();
                            break;
                        case "imageExt":
                            imageExt = temp.getExtensions();
                            break;
                        default:
                            break;
                    }
                }
            }
        }
        Map<String, String> booleanMap = Maps.newHashMap();
        for (BooleanEnum c : BooleanEnum.values()) {
            booleanMap.put(c.getCode() + "", c.getName());
        }
        model.put("booleanMap", booleanMap);
        model.put("uploadConfig", uploadConfig);
        model.put("documentExt", documentExt);
        model.put("fileExt", fileExt);
        model.put("imageExt", imageExt);
        logger.debug("uploadConfig show:" + uploadConfig.toString());
        return "/uploadify/uploadConfig";
    }

    @RequestMapping(value = "/uploadify/uploadConfig", method = RequestMethod.POST)
    public void uploadify_config_process(UploadConfig uploadConfig, HttpServletRequest request, HttpServletResponse response) {
        if (null != uploadConfig) {
            String documentExt = StringUtils.trim(request.getParameter("documentExt")),
                    fileExt = StringUtils.trim(request.getParameter("fileExt")),
                    imageExt = StringUtils.trim(request.getParameter("imageExt"));
            List<Mime_types> mime_types = Lists.newArrayList();
            Mime_types fileExtDocument = new Mime_types("documentExt", documentExt);
            Mime_types fileExtFile = new Mime_types("fileExt", fileExt);
            Mime_types fileExtImage = new Mime_types("imageExt", imageExt);
            mime_types.add(fileExtDocument);
            mime_types.add(fileExtFile);
            mime_types.add(fileExtImage);
            uploadConfig.setMime_types(mime_types);
            uploadConfig.setIsReName(Short.valueOf("1"));
//            uploadConfigRepository.save(uploadConfig);
//            //更新缓存
            SysCache.uploadConfigCache.clear();
            SysCache.uploadConfigCache.add(uploadConfig);
            succMesg(request, response);
        } else {
            errorMsg(request, response);
        }
    }


    /****
     * 配置初始化参数
     *
     * @param sizeMax
     * @param uploadConfig
     * @param request
     * @param response
     * @return
     * @throws UnsupportedEncodingException
     */
    private ServletFileUpload initConfig(long sizeMax, UploadConfig uploadConfig, HttpServletRequest request,
                                         HttpServletResponse response) throws UnsupportedEncodingException {
        // 设置上传最单个大文件尺寸
        long sizeMaxLimit = uploadConfig.getFileMaxSize() * 1024 * 1024;
        // 设置缓存大小
        int cache = uploadConfig.getCacheSize() * 1024 * 1024;
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=UTF-8");
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        factory.setSizeThreshold(cache);
        upload.setHeaderEncoding("UTF-8");
        upload.setSizeMax(sizeMax);
        upload.setFileSizeMax(sizeMaxLimit);
        return upload;
    }
}
